var net = require('net');

//sensors server's adress
var host = 'localhost';
//sensors server's port
var port = 1337;
// telegram length, in byte
var fl = 14;
 
 console.log('loading sensors module');

var client = net.connect(port, host, function() { //'connection' cb
    console.log('connected to the STC-ethernet receiver');
    open_db();
});

client.setEncoding('utf8');

client.on('data', function(datas) {
    console.log('received : ' + datas);
    var data = new Buffer(datas, 'hex');
    //Default, 'data' type is Buffer

    //note: several telegrams can be sent at the same time.
    //each telegram has the same length : fl.
    for (var i = 0; i < data.length/fl; i++) {
        var telegram = data.slice(i*fl, Math.min((i+1)*fl, data.length));
        var sensor_id = telegram.readUInt32BE(8);
        console.log("sensor_id:"+sensor_id);
        retrieve_sensor(sensor_id, function(err, row) {
            var org = telegram.readUInt8(3); //gives telegram structure
            var db0_7 = (telegram.readUInt8(7) & 128) >> 7; // data byte 0, bit 7
            var db0_3 = (telegram.readUInt8(7) & 8) >> 3; //data byte 0, bit 3
            if (err == null && row == undefined) {
                //sensor not known yet
                if (org == 7 && db0_7 == 1 && db0_3 == 0) { 
                    //4BS telegram, learn mode ?
                    learn(telegram);
                } //else sensor is not belonging to our system
            } else if (err == null && row != undefined) {
                //sensor already known
                if (org == 7 && db0_7 ==1 && db0_3 == 0) {
                    console.log('teach-in telegram ignored (sensor already known)');
                } else {
                    record(telegram);
                }
            } else if (err != null) /* obvious */ {
                console.err(err.toString());
            }
        });
    }
});

client.on('end', function() {
    console.log('disconnected');
    close_db();
});

//received telegram in "learn" mode.
//indicates sensor's type.
function learn(telegram) {
    var id_sensor = telegram.readUInt32BE(8);
    var data = telegram.readUInt32BE(4);
    var org = telegram.readUInt8(3);
    var func, type;
    func = data >> 26;
    type = (data >> 19) & 127; //127 = 0b1111111
    insert_sensor(id_sensor, org, func, type); 
}

//get relevant data from received telegram
function record(telegram) { 
    var id_sensor = telegram.readUInt32BE(8);
    var t = telegram.readUInt8(6); //temperature [0, 40°C]
    t = 40 - (40*t/250); 
    insert_data(id_sensor, t);
}

//--------------------------------------- database handling

var sqlite3 = require('sqlite3').verbose();
var db_name = 'sensors_data.db';
var db;

function open_db() {
    var fs = require('fs');
    if (fs.existsSync(db_name)) {
        db = new sqlite3.Database(db_name, sqlite3.OPEN_READWRITE);
    } else {
        db = new sqlite3.Database(db_name);
        db.serialize(function() {
            db.run("CREATE TABLE sensors (id_sensor INTEGER, org INTEGER, func INTEGER, type INTEGER)");
            db.run("CREATE TABLE data (id_sensor INTEGER, date DATETIME, data INTEGER)");
        });
    }
}

function insert_data(id_sensor, data) {
    db.run("INSERT INTO data VALUES ($id, datetime('now'), $data)", {
        $id: id_sensor,
        $data: data
    }, function(error) { //'error' cb
        if (error != null) {
            console.error(error.toString());
        }
    });
}

function insert_sensor(id_sensor, org, func, type) {
    db.run("INSERT INTO sensors VALUES ($id, $org, $func, $type)", {
        $id: id_sensor,
        $org: org,
        $func: func,
        $type: type
    }, function(error) { //'error' cb
        if (error != null) {
            console.error(error.toString());
        }
    });
}

//cb is a callback function to call with query result
//signature : cb(err, row)
function retrieve_sensor(id_sensor, cb) {
    db.get("SELECT * FROM sensors WHERE id_sensor=$id", {
        $id: id_sensor
    }, cb);
}

function close_db() {
    db.close();
}

//---------------------------------------------------------

